import Gpio from 'orange-pi-gpio'
import { startReading } from './rfid'
import { getCabinetConfig, getLockConfig } from './utils/config'
import logger from './utils/logger'

// 锁模块状态
interface LockModuleState {
  initialized: boolean
  gpio: Gpio | null
  isMonitoring: boolean
  lastError: Error | null
}

const lockState: LockModuleState = {
  initialized: false,
  gpio: null,
  isMonitoring: false,
  lastError: null,
}

// 柜子配置
let cabinetConfig: any
// 锁配置
let lockConfig: any
// 串口端口
let port: number
// 上一次读取的 GPIO 状态
let prevState: string | null = null
// 是否触发读取 RFID 标签
let triggered: boolean = false
// 是否反转开门标志
let reverseOpenFlag: boolean
// 开门标志
let openFlag: string
// 关门标志
let closeFlag: string
// 监控间隔
let monitoringInterval: NodeJS.Timeout | null = null

/**
 * 安全加载配置
 */
function loadConfigurations(): boolean {
  try {
    cabinetConfig = getCabinetConfig()
    lockConfig = getLockConfig()

    // 验证配置完整性
    if (!lockConfig || typeof lockConfig.gpioPort !== 'number') {
      throw new Error('锁配置无效: gpioPort 必须是有效的数字')
    }

    if (!lockConfig.pollInterval || lockConfig.pollInterval < 100) {
      throw new Error('锁配置无效: pollInterval 必须大于等于100ms')
    }

    if (!cabinetConfig) {
      throw new Error('柜子配置加载失败')
    }

    port = lockConfig.gpioPort
    reverseOpenFlag = !!cabinetConfig.reverseOpenFlag
    openFlag = reverseOpenFlag ? '0' : '1'
    closeFlag = reverseOpenFlag ? '1' : '0'

    return true
  }
  catch (error) {
    const err = error as Error
    lockState.lastError = err
    logger.error(`锁模块配置加载失败: ${err.message}`, {
      error: err.message,
      solution: '请检查config.json文件中的hardware.lock配置项是否正确',
    })
    return false
  }
}

/**
 * 初始化锁模块
 */
export function initLock(): void {
  logger.info('锁模块: 正在初始化...')
  try {
    // 重置状态
    lockState.initialized = false
    lockState.lastError = null

    // 加载配置
    if (!loadConfigurations()) {
      throw new Error('配置加载失败')
    }

    // 初始化GPIO
    const gpio = new Gpio({
      pin: port,
      mode: 'in',
      ready: async () => {
        prevState = await gpio.read()
        logger.info(`锁模块: 初始化完成，初始状态: ${prevState === openFlag ? '开门' : '关门'}`)
        setInterval(async () => {
          const state = await gpio.read()

          // 状态变化
          if (prevState !== state) {
            logger.info(`锁模块: 监控状态变化，当前状态: ${state === openFlag ? '开门' : '关门'}`)
          }

          // 开门
          if (state === openFlag) {
            logger.debug('锁模块: 柜门开启')
            triggered = false
          }
          // 关门
          else if (state === closeFlag) {
            if (triggered)
              return

            logger.debug('锁模块: 柜门关闭，开始读取 RFID 标签')
            startReading()
            triggered = true
          }
          prevState = state
        }, 500)
      },
    })
  }
  catch (error) {
    const err = error as Error
    lockState.lastError = err

    let solution = '请检查GPIO硬件连接和配置'
    if (err.message.includes('permission')) {
      solution = '请检查GPIO访问权限，可能需要root权限或将用户添加到gpio组'
    }
    else if (err.message.includes('busy')) {
      solution = 'GPIO引脚被占用，请检查是否有其他程序正在使用该引脚'
    }
    else if (err.message.includes('not found')) {
      solution = '找不到指定的GPIO引脚，请检查引脚编号是否正确'
    }

    logger.error(`锁模块初始化失败: ${err.message}`, {
      error: err.message,
      solution,
    })

    throw err
  }
}

/**
 * 获取锁模块状态
 */
export function getLockStatus(): LockModuleState {
  return { ...lockState }
}

/**
 * 停止锁模块监控
 */
export function stopLockMonitoring(): void {
  try {
    lockState.isMonitoring = false

    if (monitoringInterval) {
      clearInterval(monitoringInterval)
      monitoringInterval = null
    }

    logger.info('锁模块: 监控已停止')
  }
  catch (error) {
    const err = error as Error
    logger.error('锁模块: 停止监控时发生错误', {
      error: err.message,
    })
  }
}
